﻿#ifndef JZNET_FILE_TRANS_H_
#define JZNET_FILE_TRANS_H_

#include <QTimer>
#include <QFile>
#include "JZNetPack.h"
#include "JZNetClient.h"
#include "JZNetServer.h"

//JZNetPackFileOperatorf
class JZNetPackFileOperatorReq : public JZNetPack
{
public:
    enum {
        Pull,
        Push,
    };

	JZNetPackFileOperatorReq();
	virtual ~JZNetPackFileOperatorReq();

	virtual int type() const;
	virtual void saveToStream(QDataStream& s) const;
	virtual void loadFromStream(QDataStream& s);

    int method;
	int taskId;
    qint64 localFileSize;  //本地文件大小
	QString remoteFile;    
};

//JZNetPackFileOperator
class JZNetPackFileOperatorRes : public JZNetPack
{
public:
    JZNetPackFileOperatorRes();
    virtual ~JZNetPackFileOperatorRes();

    virtual int type() const;
    virtual void saveToStream(QDataStream& s) const;
    virtual void loadFromStream(QDataStream& s);

	int taskId;          //本地id
	qint64 fileSize;     //本地文件大小
	int remoteTaskId;    //远端id
    QString error;
};

//JZNetPackFileReq
class JZNetPackFileReq : public JZNetPack
{
public:
	JZNetPackFileReq();
	virtual ~JZNetPackFileReq();

	virtual int type() const;
	virtual void saveToStream(QDataStream& s) const;
	virtual void loadFromStream(QDataStream& s);

	int remoteTaskId;
	qint64 offset;
};

//JZNetPackFileRes
class JZNetPackFileRes : public JZNetPack
{
public:
	JZNetPackFileRes();
	virtual ~JZNetPackFileRes();

	virtual int type() const;
	virtual void saveToStream(QDataStream& s) const;
	virtual void loadFromStream(QDataStream& s);
	
	int remoteTaskId;
	bool ok;	
	QByteArray buffer;
};

class JZNetFileTask
{
public:
    enum Type{
        Send,
        Recv,
    };

    JZNetFileTask();

    Type type;
	int netId;
	int taskId;
	int remoteTaskId;
    bool error;

	QFile file;
	QString filePath;
	qint64 fileSize;
	qint64 offset;
};
typedef QSharedPointer<JZNetFileTask> JZNetFileTaskPtr;

/*
先发送 JZNetPackFileOperatorReq 建立通道，通道建立后，总是由数据发送方发送 JZNetPackFileReq
*/
class JZNetFileTrans : public QObject
{
	Q_OBJECT

public:
    static bool isFilePack(int type);
    static void registPack();

	JZNetFileTrans(QObject *parent = nullptr);
	~JZNetFileTrans();
	
	void setClient(JZNetClient *client);
	void setServer(JZNetServer *server);
	void setDir(QString path);

	JZNetFileTaskPtr startPush(int net_id,QString localUrl, QString remoteUrl);
	JZNetFileTaskPtr startPull(int net_id,QString remoteUrl,QString localUrl);
	void recvPack(int net_id,JZNetPackPtr pack);

signals:
	void sigNewTask(JZNetFileTaskPtr task);
	void sigTaskFinish(JZNetFileTaskPtr task);

protected slots:


protected:
	QString fullPath(QString path);
	void sendPack(int net_id, const JZNetPack* pack);
	int getRemoteTaskId(const JZNetPack* pack);
	void sendFileReq(JZNetFileTask* task);

	JZNetFileTaskPtr startTask(int net_id, JZNetFileTask::Type req_type,QString localUrl, QString remoteUrl);
	void taskFinish(int task_id);

	QMap<int,JZNetFileTaskPtr> m_tasks;
	JZNetServer* m_server;
	JZNetClient* m_client;
	QString m_path;
	int m_taskId;
	int m_eachRoundSize;
};

#endif
